#lang racket


(require "../base/main.rkt")

(require "parametric.rkt")

(provide (struct-out transformation-parametric)
         transformation-parametric-object-default
         transformation-parametric-tangent-default
         transformation-parametric-normal-default
         transformation-parametric-binormal-default
         make-transformation-parametric)


(define-struct (transformation-parametric parametric)
  (parametric transformation)
  #:constructor-name new-transformation-parametric)

(define (matrix*coords matrix coord/coords vector?)
  (if (coord? coord/coords)
      (m*p matrix coord/coords vector?)
      (map (λ (p) (m*p matrix p vector?)) coord/coords)))

(define (transformation-parametric-object-default parametric transformation)
  (λ args
    (matrix*coords
     transformation
     (apply (parametric-object parametric) args)
     #f)))

(define (transformation-parametric-tangent-default parametric transformation)
  (λ args
    (matrix*coords
     transformation
     (apply (parametric-tangent parametric) args)
     #t)))

(define (transformation-parametric-normal-default parametric transformation)
  (λ args
    (matrix*coords
     transformation
     (apply (parametric-normal parametric) args)
     #t)))

(define (transformation-parametric-binormal-default parametric transformation)
  (λ args
    (matrix*coords
     transformation
     (apply (parametric-binormal parametric) args)
     #t)))

(define (make-transformation-parametric parametric transformation)
  (new-transformation-parametric
   (transformation-parametric-object-default parametric transformation)
   (transformation-parametric-tangent-default parametric transformation)
   (transformation-parametric-normal-default parametric transformation)
   (transformation-parametric-binormal-default parametric transformation)
   (parametric-domain parametric)
   parametric
   transformation))